home *** CD-ROM | disk | FTP | other *** search
/ Enter 2006 September / Enter 09 2006.iso / Internet / SpamExperts Home 1.1 / SpamExperts Home.exe / lib / spamexperts.modules / persistent / wref.pyc (.txt) < prev   
Encoding:
Python Compiled Bytecode  |  2006-07-14  |  8.3 KB  |  305 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. '''ZODB-based persistent weakrefs
  5.  
  6. $Id: wref.py 29450 2005-03-11 23:53:09Z tim_one $
  7. '''
  8. from persistent import Persistent
  9. WeakRefMarker = object()
  10.  
  11. class WeakRef(object):
  12.     """Persistent weak references
  13.  
  14.     Persistent weak references are used much like Python weak
  15.     references.  The major difference is that you can't specify an
  16.     object to be called when the object is removed from the database.
  17.  
  18.     Here's an example. We'll start by creating a persistent object and
  19.     a refernce to it:
  20.  
  21.     >>> import persistent.list
  22.     >>> import ZODB.tests.util
  23.     >>> ob = persistent.list.PersistentList()
  24.     >>> ref = WeakRef(ob)
  25.     >>> ref() is ob
  26.     True
  27.  
  28.     The hash of the ref if the same as the hash of the referenced object:
  29.  
  30.     >>> hash(ref) == hash(ob)
  31.     True
  32.  
  33.     Two refs to the same object are equal:
  34.  
  35.     >>> WeakRef(ob) == ref
  36.     True
  37.  
  38.     >>> ob2 = persistent.list.PersistentList([1])
  39.     >>> WeakRef(ob2) == ref
  40.     False
  41.  
  42.     Lets save the reference and the referenced object in a database:
  43.  
  44.     >>> db = ZODB.tests.util.DB()
  45.  
  46.     >>> conn1 = db.open()
  47.     >>> conn1.root()['ob'] = ob
  48.     >>> conn1.root()['ref'] = ref
  49.     >>> ZODB.tests.util.commit()
  50.  
  51.     If we open a new connection, we can use the reference:
  52.  
  53.     >>> conn2 = db.open()
  54.     >>> conn2.root()['ref']() is conn2.root()['ob']
  55.     True
  56.     >>> hash(conn2.root()['ref']) == hash(conn2.root()['ob'])
  57.     True
  58.  
  59.     But if we delete the referenced object and pack:
  60.  
  61.     >>> del conn2.root()['ob']
  62.     >>> ZODB.tests.util.commit()
  63.     >>> ZODB.tests.util.pack(db)
  64.  
  65.     And then look in a new connection:
  66.  
  67.     >>> conn3 = db.open()
  68.     >>> conn3.root()['ob']
  69.     Traceback (most recent call last):
  70.     ...
  71.     KeyError: 'ob'
  72.  
  73.     Trying to dereference the reference returns None:
  74.  
  75.     >>> conn3.root()['ref']()
  76.  
  77.     Trying to get a hash, raises a type error:
  78.  
  79.     >>> hash(conn3.root()['ref'])
  80.     Traceback (most recent call last):
  81.     ...
  82.     TypeError: Weakly-referenced object has gone away
  83.  
  84.     Always explicitly close databases: :)
  85.  
  86.     >>> db.close()
  87.  
  88.     """
  89.     _p_oid = WeakRefMarker
  90.     
  91.     def __init__(self, ob):
  92.         self._v_ob = ob
  93.         self.oid = ob._p_oid
  94.         self.dm = ob._p_jar
  95.  
  96.     
  97.     def __call__(self):
  98.         
  99.         try:
  100.             return self._v_ob
  101.         except AttributeError:
  102.             
  103.             try:
  104.                 self._v_ob = self.dm[self.oid]
  105.             except KeyError:
  106.                 return None
  107.  
  108.             return self._v_ob
  109.  
  110.  
  111.     
  112.     def __hash__(self):
  113.         self = self()
  114.         if self is None:
  115.             raise TypeError('Weakly-referenced object has gone away')
  116.         
  117.         return hash(self)
  118.  
  119.     
  120.     def __eq__(self, other):
  121.         self = self()
  122.         if self is None:
  123.             raise TypeError('Weakly-referenced object has gone away')
  124.         
  125.         other = other()
  126.         if other is None:
  127.             raise TypeError('Weakly-referenced object has gone away')
  128.         
  129.         return self == other
  130.  
  131.  
  132.  
  133. class PersistentWeakKeyDictionary(Persistent):
  134.     """Persistent weak key dictionary
  135.  
  136.     This is akin to WeakKeyDictionaries. Note, however, that removal
  137.     of items is extremely lazy. See below.
  138.  
  139.     We'll start by creating a PersistentWeakKeyDictionary and adding
  140.     some persistent objects to it.
  141.  
  142.     >>> d = PersistentWeakKeyDictionary()
  143.     >>> import ZODB.tests.util
  144.     >>> p1 = ZODB.tests.util.P('p1')
  145.     >>> p2 = ZODB.tests.util.P('p2')
  146.     >>> p3 = ZODB.tests.util.P('p3')
  147.     >>> d[p1] = 1
  148.     >>> d[p2] = 2
  149.     >>> d[p3] = 3
  150.  
  151.     We'll create an extra persistent object that's not in the dict:
  152.  
  153.     >>> p4 = ZODB.tests.util.P('p4')
  154.  
  155.     Now we'll excercise iteration and item access:
  156.  
  157.     >>> l = [(str(k), d[k], d.get(k)) for k in d]
  158.     >>> l.sort()
  159.     >>> l
  160.     [('P(p1)', 1, 1), ('P(p2)', 2, 2), ('P(p3)', 3, 3)]
  161.  
  162.     And the containment operator:
  163.  
  164.     >>> [p in d for p in [p1, p2, p3, p4]]
  165.     [True, True, True, False]
  166.  
  167.     We can add the dict and the referenced objects to a database:
  168.  
  169.     >>> db = ZODB.tests.util.DB()
  170.  
  171.     >>> conn1 = db.open()
  172.     >>> conn1.root()['p1'] = p1
  173.     >>> conn1.root()['d'] = d
  174.     >>> conn1.root()['p2'] = p2
  175.     >>> conn1.root()['p3'] = p3
  176.     >>> ZODB.tests.util.commit()
  177.  
  178.     And things still work, as before:
  179.  
  180.     >>> l = [(str(k), d[k], d.get(k)) for k in d]
  181.     >>> l.sort()
  182.     >>> l
  183.     [('P(p1)', 1, 1), ('P(p2)', 2, 2), ('P(p3)', 3, 3)]
  184.     >>> [p in d for p in [p1, p2, p3, p4]]
  185.     [True, True, True, False]
  186.  
  187.     Likewise, we can read the objects from another connection and
  188.     things still work.
  189.  
  190.     >>> conn2 = db.open()
  191.     >>> d = conn2.root()['d']
  192.     >>> p1 = conn2.root()['p1']
  193.     >>> p2 = conn2.root()['p2']
  194.     >>> p3 = conn2.root()['p3']
  195.     >>> l = [(str(k), d[k], d.get(k)) for k in d]
  196.     >>> l.sort()
  197.     >>> l
  198.     [('P(p1)', 1, 1), ('P(p2)', 2, 2), ('P(p3)', 3, 3)]
  199.     >>> [p in d for p in [p1, p2, p3, p4]]
  200.     [True, True, True, False]
  201.  
  202.     Now, we'll delete one of the objects from the database, but *not*
  203.     from the dictionary:
  204.  
  205.     >>> del conn2.root()['p2']
  206.     >>> ZODB.tests.util.commit()
  207.  
  208.     And pack the database, so that the no-longer referenced p2 is
  209.     actually removed from the database.
  210.  
  211.     >>> ZODB.tests.util.pack(db)
  212.  
  213.     Now if we access the dictionary in a new connection, it no longer
  214.     has p2:
  215.  
  216.     >>> conn3 = db.open()
  217.     >>> d = conn3.root()['d']
  218.     >>> l = [(str(k), d[k], d.get(k)) for k in d]
  219.     >>> l.sort()
  220.     >>> l
  221.     [('P(p1)', 1, 1), ('P(p3)', 3, 3)]
  222.  
  223.     It's worth nothing that that the versions of the dictionary in
  224.     conn1 and conn2 still have p2, because p2 is still in the caches
  225.     for those connections.
  226.  
  227.     Always explicitly close databases: :)
  228.  
  229.     >>> db.close()
  230.  
  231.     """
  232.     
  233.     def __init__(self, adict = None, **kwargs):
  234.         self.data = { }
  235.         if adict is not None:
  236.             keys = getattr(adict, 'keys', None)
  237.             if keys is None:
  238.                 adict = dict(adict)
  239.             
  240.             self.update(adict)
  241.         
  242.         if kwargs:
  243.             self.update(kwargs)
  244.         
  245.  
  246.     
  247.     def __getstate__(self):
  248.         state = Persistent.__getstate__(self)
  249.         state['data'] = state['data'].items()
  250.         return state
  251.  
  252.     
  253.     def __setstate__(self, state):
  254.         state['data'] = [](_[1])
  255.         Persistent.__setstate__(self, state)
  256.  
  257.     
  258.     def __setitem__(self, key, value):
  259.         self.data[WeakRef(key)] = value
  260.  
  261.     
  262.     def __getitem__(self, key):
  263.         return self.data[WeakRef(key)]
  264.  
  265.     
  266.     def __delitem__(self, key):
  267.         del self.data[WeakRef(key)]
  268.  
  269.     
  270.     def get(self, key, default = None):
  271.         '''D.get(k[, d]) -> D[k] if k in D, else d.
  272.  
  273.         >>> import ZODB.tests.util
  274.         >>> key = ZODB.tests.util.P("key")
  275.         >>> missing = ZODB.tests.util.P("missing")
  276.         >>> d = PersistentWeakKeyDictionary([(key, 1)])
  277.         >>> d.get(key)
  278.         1
  279.         >>> d.get(missing)
  280.         >>> d.get(missing, 12)
  281.         12
  282.         '''
  283.         return self.data.get(WeakRef(key), default)
  284.  
  285.     
  286.     def __contains__(self, key):
  287.         return WeakRef(key) in self.data
  288.  
  289.     
  290.     def __iter__(self):
  291.         for k in self.data:
  292.             yield k()
  293.         
  294.  
  295.     
  296.     def update(self, adict):
  297.         if isinstance(adict, PersistentWeakKeyDictionary):
  298.             self.data.update(adict.update)
  299.         else:
  300.             for k, v in adict.items():
  301.                 self.data[WeakRef(k)] = v
  302.             
  303.  
  304.  
  305.